(:
Part 2 / Q8
An XML document called report.xml (satisfying the DTD in file report.dtd) that
contains a full report for each student in class.xml. This includes the student
IDs and, for each question on the quiz, the QID, the students answer to the 
question (or empty text if they gave none), their mark for that question and
the student's total score.
:)

(:
Return 1 * $weight if student answer $st_ans matches the answer key $ans_key.
:)
declare function local:mark ($st_ans as xs:string, $ans_key as xs:string,
    $weight as xs:integer) as xs:integer
{
    if ($st_ans eq $ans_key) then 1*$weight else (0)
};

(: 
Return a sequence of Question elements, which are Student $student's results
to Quiz $quiz. Use QuestionBank $bank to check answers.
:)
declare function local:get_quiz_results($student, $quiz, $bank) as element()*
{
    let $answered_by_student := 
        for $ans in $student/QuestionResponse 
        return data($ans/@QID)
    for $q in $quiz/Question
    let $qid := data($q/@QID)
    return
        if ($answered_by_student = $qid)
        then 
            (<Question qid="{$qid}"
             score="{local:mark(
             $student/QuestionResponse[@QID eq $qid]/@Response,
             $bank/Question/*[@QID eq $qid]/@answer, $q/@weight)}" />)
        else (<Question qid="{$qid}" score="0" />)
};

(: Return the sum of scores received for the Questions in $questions. :)
declare function local:calc_total_score($questions) as xs:double
{
    sum(for $q in $questions return number($q/@score))
};

(: -- Query -- :)
<ClassReport>
{
for $s in fn:doc("class.xml")/ClassResponses/Student
let $questions := local:get_quiz_results($s, fn:doc("quiz.xml")/Quiz, 
    fn:doc("bank.xml")/QuestionBank)
return 
    <Student 
        sid="{data($s/@sid)}"
        total="{local:calc_total_score($questions)}">
    {$questions}
    </Student>
}
</ClassReport>
